package com.cmj.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cmj.Utils.BeanCopyUtils;
import com.cmj.Utils.IsExistUtils;
import com.cmj.Utils.SecurityUtils;
import com.cmj.Utils.SetCbytimeUbytime;
import com.cmj.dao.UserMapper;
import com.cmj.domain.AppHttpCodeEnum;
import com.cmj.domain.ResponseResult;
import com.cmj.domain.SystemConstants;
import com.cmj.domain.dto.UserDto;
import com.cmj.domain.dto.UserStatusDto;
import com.cmj.domain.entity.Role;
import com.cmj.domain.entity.User;
import com.cmj.domain.entity.UserRole;
import com.cmj.domain.vo.*;
import com.cmj.exception.SystemException;
import com.cmj.service.RoleService;
import com.cmj.service.UserRoleService;
import com.cmj.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;


/**
 * 用户表(User)表服务实现类
 *
 * @author makejava
 * @since 2022-03-15 11:17:49
 */
@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService {
    @Resource
    private UserMapper userMapper;

    @Autowired
    private RoleService roleService;

    @Resource
    private UserRoleService userRoleService;

    /***
     * 根据用户id获取用户
     * @return 用户信息
     */
    @Override
    public ResponseResult userInfo() {
        User userById = userMapper.getUserById(SecurityUtils.getUserId());
        UserVo userVo = BeanCopyUtils.copyBean(userById, UserVo.class);
        return ResponseResult.okResult(userVo);
    }

    /**
     * 更新用户信息
     * @param user 用户表单
     * @return 操作结果
     */
    @Transactional
    @Override
    public ResponseResult updateUserInfo(User user) {
        //设置更新时间
        SetCbytimeUbytime.setUpdate(user);
        //更新用户
        int result = userMapper.updateUser(user);
        if (result == 0){
            throw new RuntimeException("更新失败，请稍后重试！");
        }
        return ResponseResult.okResult();
    }

    /**
     * 注册
     * @param user{
     *   "email": "string",
     *   "nickName": "string",
     *   "password": "string",
     *   "userName": "string"
     * }
     * @return 操作结果
     */
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Transactional
    @Override
    public ResponseResult register(User user) {
        //判断数据是否为空
        if (!StringUtils.hasText(user.getUserName())){
            throw new SystemException(AppHttpCodeEnum.REQUIRE_USERNAME);
        }
        if(!StringUtils.hasText(user.getPassword())){
            throw new SystemException(AppHttpCodeEnum.REQUIRE_PASSWORD);
        }
        if(!StringUtils.hasText(user.getEmail())){
            throw new SystemException(AppHttpCodeEnum.REQUIRE_EMAIL);
        }
        if(!StringUtils.hasText(user.getNickName())){
            throw new SystemException(AppHttpCodeEnum.REQUIRE_NICKNAME);
        }
        //nickName,userName,email不能重复
        IsExistUtils.isOnly(user,userMapper);
        //密码加密
        String encode = passwordEncoder.encode(user.getPassword());
        user.setPassword(encode);
        //获取创建时间
        SetCbytimeUbytime.setCreate(user);
        //写入数据库
        int i = userMapper.addUser(user);
        if (i == 0){
            throw new RuntimeException("注册失败，请重新注册");
        }
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult<UserNewVo> getUserList(Integer pageNum, Integer pageSize, UserDto userDto) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.hasText(userDto.getUserName()),User::getUserName,userDto.getUserName());
        wrapper.eq(StringUtils.hasText(userDto.getStatus()),User::getStatus,userDto.getStatus());
        wrapper.eq(StringUtils.hasText(userDto.getPhoneNumber()),User::getPhonenumber,userDto.getPhoneNumber());

        Page<User> userPage = new Page<>();
        userPage.setCurrent(pageNum);
        userPage.setSize(pageSize);
        page(userPage,wrapper);

        List<UserNewVo> userNewVos = BeanCopyUtils.copyBeanList(userPage.getRecords(), UserNewVo.class);
        PageVo pageVo = new PageVo(userNewVos, userPage.getTotal());

        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult getUser(Long id) {
        UserUpdateVo userUpdateVo = new UserUpdateVo();
        userUpdateVo.setUser(userMapper.selectById(id));
        userUpdateVo.setRoleIds(roleService.getAllUserRole(id));
        List<RoleVo> roleVos = BeanCopyUtils.copyBeanList((List<Role>) roleService.listAllRole().getData(), RoleVo.class);
        userUpdateVo.setRoles(roleVos);
        return ResponseResult.okResult(userUpdateVo);
    }

    @Override
    public ResponseResult delUser(Long[] ids) {
        int i = userMapper.deleteBatchIds(Arrays.asList(ids));
        if (i == 0){
            new RuntimeException(SystemConstants.DELETE_FAIL);
        }
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult addUser(User user) {
        //nickName,userName,email不能重复
        IsExistUtils.isOnly(user,userMapper);
        //密码加密
        String encode = passwordEncoder.encode(user.getPassword());
        user.setPassword(encode);

        int insert = userMapper.insert(user);

        for (Integer roleId : user.getRoleIds()) {
            UserRole userRole = new UserRole();
            userRole.setUserId(user.getId());
            userRole.setRoleId(roleId);
            userMapper.addUserRole(userRole);
        }
        if (insert == 0){
            new RuntimeException(SystemConstants.INSERT_FAIL);
        }
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult changeStatus(UserStatusDto userStatusDto) {
        User user = new User();
        user.setId(userStatusDto.getUserId());
        user.setStatus(userStatusDto.getStatus());
        int i = userMapper.updateById(user);
        if (i == 0){
            new RuntimeException(SystemConstants.UPDATE_FAIL);
        }
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult updateUser(User user) {
        int i = userMapper.updateById(user);
        userRoleService.delUserRole(user.getId());
        for (Integer roleId : user.getRoleIds()) {
            UserRole userRole = new UserRole();
            userRole.setUserId(user.getId());
            userRole.setRoleId(roleId);
            userRoleService.addUserRole(userRole);
        }
        if (i == 0){
            new RuntimeException(SystemConstants.UPDATE_FAIL);
        }
        return ResponseResult.okResult();
    }


}
